﻿using System;
using System.Text;
using System.Xml;

namespace LitS3
{
    public enum DistributionStatus
    {
        InProgress,
        Deployed
    }

    public class DistributionConfig
    {
        public string Origin;
        public string CallerReference { get; internal set; }
        public string CName;
        public string Comment;
        public bool Enabled;

        public DistributionConfig()
        {
            this.CallerReference = Guid.NewGuid().ToString().Replace("-", String.Empty);
        }

        public string ToXmlString()
        {
            StringBuilder xml = new StringBuilder(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<DistributionConfig xmlns=\"http://cloudfront.amazonaws.com/doc/2008-06-30/\">\n");

            if (!String.IsNullOrEmpty(Origin)) xml.AppendFormat("   <Origin>{0}</Origin>\n", Origin);
            else xml.Append("   <Origin/>\n");

            if (!String.IsNullOrEmpty(CallerReference)) xml.AppendFormat("   <CallerReference>{0}</CallerReference>\n", CallerReference);
            else xml.Append("   <CallerReference/>\n");

            if (!String.IsNullOrEmpty(CName)) xml.AppendFormat("   <CNAME>{0}</CNAME>\n", CName);

            if (!String.IsNullOrEmpty(Comment)) xml.AppendFormat("   <Comment>{0}</Comment>\n", Comment);

            xml.AppendFormat("   <Enabled>{0}</Enabled>\n", Enabled.ToString().ToLower());

            xml.Append("</DistributionConfig>");

            return xml.ToString();
        }
    }

    /// <summary>
    /// Represents a distribution hosted by Amazon S3 that contains objects.
    /// </summary>
    public sealed class Distribution
    {
        public string ID { get; private set; }

        public DistributionStatus Status { get; private set; }

        public DistributionConfig Config { get; private set; }

        public string DomainName { get; private set; }

        public DateTime LastModifiedTime { get; private set; }

        internal Distribution(XmlReader reader)
        {
            if (reader.IsEmptyElement)
                throw new Exception("Expected a non-empty <Distribution> element.");

            // This will parse the <Distribution> returned from creating a new distribution
            // and the <DistributionSummary> returned from listing current distributions
            reader.ReadStartElement();

            this.ID = reader.ReadElementContentAsString("Id", "");
            this.Status = (reader.ReadElementContentAsString("Status", "") == "Deployed") ?
                DistributionStatus.Deployed : DistributionStatus.InProgress;
            this.LastModifiedTime = reader.ReadElementContentAsDateTime("LastModifiedTime", "");
            this.DomainName = reader.ReadElementContentAsString("DomainName", "");

            bool configWrapper = false;
            if (reader.Name == "DistributionConfig")
            {
                reader.ReadStartElement("DistributionConfig");
                configWrapper = true;
            }

            DistributionConfig config = new DistributionConfig();
            config.Origin = reader.ReadElementContentAsString("Origin", "");
            if (reader.Name == "CallerReference")
                config.CallerReference = reader.ReadElementContentAsString("CallerReference", "");
            else
                config.CallerReference = String.Empty;

            while (reader.Name == "CNAME")
                config.CName = reader.ReadElementContentAsString("CNAME", "");

            if (reader.Name == "Comment")
                config.Comment = reader.ReadElementContentAsString("Comment", "");

            config.Enabled = reader.ReadElementContentAsBoolean("Enabled", "");
            this.Config = config;

            if (configWrapper)
                reader.ReadEndElement();

            reader.ReadEndElement();
        }

        public override string ToString()
        {
            return "Distribution " + ID;
        }
    }
}
